package pl.edu.agh.pros.proxy.view.key;

import java.util.Arrays;
import java.util.Collection;

import pl.edu.agh.pros.proxy.logic.dao.AppConfigurationDAO;
import pl.edu.agh.pros.proxy.logic.wrapper.AppConfigurationWrapper;
import pl.edu.agh.pros.proxy.model.AppConfiguration;
import pl.edu.agh.pros.proxy.utils.KeyPair;
import pl.edu.agh.pros.proxy.utils.KeyPairGenerator;
import pl.edu.agh.pros.proxy.view.xmpp.XmppServersTable;

import com.google.appengine.api.datastore.Key;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanItem;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
public class AppKeysLayout extends VerticalLayout {

	private static final ThemeResource icon1 = new ThemeResource("images/add.png");
	private static final ThemeResource icon2 = new ThemeResource("images/delete.png");

	private static final AppConfigurationDAO APP_DAO = AppConfigurationDAO.getInstance();
	private Collection<AppConfigurationWrapper> configurations;
	private AppConfigurationWrapper newConfiguration;
	private AppConfigurationWrapper selectedConfiguration;
	private AppKeysForm editForm;

	public AppKeysLayout(final Key providerKey, XmppServersTable xmppServersTable) {

		if (providerKey != null) {
			configurations = APP_DAO.getAppConfigurations(providerKey);
		}

		HorizontalLayout horizontalLayout = new HorizontalLayout();

		// Bind a table to it
		final AppKeysTable table = new AppKeysTable(configurations);

		final Button newButton = new Button("New");
		final Button deleteButton = new Button("Delete");

		horizontalLayout.addComponent(table);
		horizontalLayout.setSpacing(true);

		editForm = new AppKeysForm(xmppServersTable);
		editForm.setVisible(false);
		horizontalLayout.addComponent(editForm);

		// When the user selects an item, show it in the form
		table.addListener(new Property.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				newConfiguration = null;
				if (event.getProperty().getValue() == null) {
					editForm.setVisible(false);
				} else {
					selectedConfiguration = (AppConfigurationWrapper) event.getProperty().getValue();
					deleteButton.setEnabled(true);
					editForm.setItemDataSource(table.getItem(table.getValue()));
					editForm.setCaption("Edit");
					editForm.setVisibleItemProperties(Arrays.asList(new String[] { "name", "xmppServerConfiguration",
							"providerAppKey", "clientAppKey" }));
					editForm.getField("xmppServerConfiguration").setValue(selectedConfiguration.getXmppServerConfiguration());
					editForm.setVisible(true);
				}
			}
		});

		HorizontalLayout buttonsLayout = new HorizontalLayout();
		buttonsLayout.setSpacing(true);

		newButton.setIcon(icon1);
		newButton.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				newConfiguration = new AppConfigurationWrapper(new AppConfiguration());
				selectedConfiguration = null;
				BeanItem<AppConfigurationWrapper> beanItem = new BeanItem<AppConfigurationWrapper>(newConfiguration);
				editForm.setItemDataSource(beanItem);
				editForm.setCaption("Create");
				editForm.setVisibleItemProperties(Arrays.asList(new String[] { "name", "xmppServerConfiguration" }));
				editForm.setVisible(true);
				newButton.setEnabled(false);
			}
		});

		deleteButton.setIcon(icon2);
		deleteButton.setEnabled(false);
		deleteButton.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				if (table.getValue() != null) {
					editForm.setVisible(false);
					table.removeItem(table.getValue());
					table.commit();
					table.setValue(null);
					deleteButton.setEnabled(false);
					newButton.setEnabled(true);
					APP_DAO.deleteConfiguration(selectedConfiguration);
				}
			}
		});
		buttonsLayout.addComponent(newButton);
		buttonsLayout.addComponent(deleteButton);
		addComponent(buttonsLayout);
		addComponent(horizontalLayout);

		final Button submitButton = new Button("Save");
		submitButton.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				editForm.commit();
				editForm.setVisible(false); // and close it
				table.setValue(null);

				// New items have to be added to the container
				if (newConfiguration != null) {
					newButton.setEnabled(true);
					KeyPair keyPair = KeyPairGenerator.generateKeys(String.valueOf(providerKey.getId()));
					newConfiguration.setClientAppKey(keyPair.getClientAppKey());
					newConfiguration.setProviderAppKey(keyPair.getProviderAppKey());
					table.getContainerDataSource().addItem(newConfiguration);
					table.commit();
					APP_DAO.saveNewConfiguration(newConfiguration, providerKey);
				} else if (selectedConfiguration != null) {
					APP_DAO.updateConfiguration(selectedConfiguration);
				}
			}
		});
		editForm.getFooter().addComponent(submitButton);

		Button cancel = new Button("Cancel");
		cancel.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				editForm.discard(); // Not really necessary
				editForm.setVisible(false); // and close it
				table.discard(); // Discards possible addItem()
				table.setValue(null);
				newConfiguration = null;
				selectedConfiguration = null;
				newButton.setEnabled(true);
			}
		});
		editForm.getFooter().addComponent(cancel);

	}
}